<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:sparql="http://www.w3.org/2005/sparql-results#">

    <xsl:strip-space elements="*" />
    <xsl:template    match="node()|@*|text()"/>
    <xsl:template    match="text()" mode="header"/>
    <xsl:template    match="node()" mode="results"/>
    <xsl:output      method="text" />
    <xsl:param       name="ignore-bnode" select="false()"/>
    <xsl:template match="/">
        {
            <xsl:apply-templates select="sparql:sparql"/>
        }
    </xsl:template>
    <xsl:template match="sparql:boolean" mode="results">
        "head"    : {},
        "boolean" : <xsl:value-of select="text()"/>
    </xsl:template>
    <xsl:template match="sparql:results" mode="results">
        <xsl:apply-templates select="../sparql:head" mode="header"/>
        "results": {
            "bindings": [
                <xsl:apply-templates select="sparql:result" mode="results"/>
            ]
        }
    </xsl:template>
    <xsl:template match="sparql:sparql">
        <xsl:apply-templates select="sparql:results|sparql:boolean" mode="results"/>
    </xsl:template>
    <xsl:template match="sparql:head" mode="header">
        "head":
            { "vars": [
                <xsl:apply-templates mode="header" select="sparql:variable"/>
              ]
            },
    </xsl:template>
    <xsl:template match="sparql:result" mode="results">
        {
            <xsl:for-each select="sparql:binding">
                "<xsl:value-of select="@name"/>" : {
                    <xsl:apply-templates mode="value" select="*"/>
                }
                <xsl:if test="position() != last()">,</xsl:if>
            </xsl:for-each>
        }<xsl:if test="position() != last()">,</xsl:if>
    </xsl:template>
    <xsl:template match="sparql:bnode" mode="value">
        "type":"<xsl:value-of select="local-name()"/>",
        <xsl:choose>
            <xsl:when test="$ignore-bnode">
                "value":""
            </xsl:when>
            <xsl:otherwise>
                "value":"<xsl:value-of select="text()"/>"
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>    
    <xsl:template match="sparql:uri" mode="value">
        "type":"<xsl:value-of select="local-name()"/>",
        "value":"<xsl:value-of select="text()"/>"
    </xsl:template>
    <xsl:template match="sparql:literal" mode="value">
        "type":"<xsl:choose>
                <xsl:when test="@datatype">typed-literal</xsl:when>
                <xsl:otherwise>literal</xsl:otherwise>
            </xsl:choose>",
        "value":"<xsl:value-of select="text()"/>"
        <xsl:choose>
            <xsl:when test="@xml:lang">
                ,"xml:lang":"<xsl:value-of select="@xml:lang"/>"
            </xsl:when>
            <xsl:when test="@datatype">
                ,"datatype":"<xsl:value-of select="@datatype"/>"
            </xsl:when>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="sparql:variable" mode="header">
        "<xsl:value-of select="@name"/>"
        <xsl:if test="position() != last()">,</xsl:if>
    </xsl:template>
</xsl:stylesheet>